﻿using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Autodesk.Revit.UI;

namespace RevitCommands
{
	public class Press
	{
		[DllImport("USER32.DLL")]
		public static extern bool PostMessage(IntPtr hWnd, uint msg, uint wParam, uint lParam);

		[DllImport("user32.dll")]
		private static extern uint MapVirtualKey(uint uCode, uint uMapType);

		private static void OneKey(IntPtr handle, char letter)
		{
			uint num = Press.MapVirtualKey((uint)letter, 0u);
			uint lParam = 0u | num << 16;
			uint lParam2 = 3221225473u | num << 16;
			Press.PostMessage(handle, 256u, (uint)letter, lParam);
			Press.PostMessage(handle, 257u, (uint)letter, lParam2);
		}

		public static void Keys(string command, bool pressEnter = false)
		{
			IntPtr mainWindowHandle = Process.GetCurrentProcess().MainWindowHandle;
			foreach (char letter in command)
			{
				Press.OneKey(mainWindowHandle, letter);
			}
			if (pressEnter)
			{
				Press.PressEnter();
			}
		}

		public static void PostOrPressByVersion(string shortcuts, RevitCommandId cmdId, ExternalCommandData cmdData)
		{
			if (Convert.ToInt32(cmdData.Application.Application.VersionNumber) < 2019)
			{
				Press.Keys(shortcuts, false);
				return;
			}
			cmdData.Application.PostCommand(cmdId);
		}

		[DllImport("user32.dll")]
		private static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);

		private static void PressEnter()
		{
			int bVk = 13;
			int dwFlags = 0;
			int dwFlags2 = 2;
			Press.keybd_event((byte)bVk, 0, dwFlags, 0);
			Press.keybd_event((byte)bVk, 0, dwFlags2, 0);
		}

		private static void PressSpace()
		{
			int bVk = 32;
			int dwFlags = 0;
			int dwFlags2 = 2;
			Press.keybd_event((byte)bVk, 0, dwFlags, 0);
			Press.keybd_event((byte)bVk, 0, dwFlags2, 0);
		}

		private enum WH_KEYBOARD_LPARAM : uint
		{
			KEYDOWN,
			KEYUP = 3221225473u
		}

		private enum KEYBOARD_MSG : uint
		{
			WM_KEYDOWN = 256u,
			WM_KEYUP
		}

		private enum MVK_MAP_TYPE : uint
		{
			VKEY_TO_SCANCODE,
			SCANCODE_TO_VKEY,
			VKEY_TO_CHAR,
			SCANCODE_TO_LR_VKEY
		}
	}
}
